package cn.jeeweb.common.mybatis.mvc.service.impl;

import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.jeeweb.common.annotate.UiPropertyField;
import cn.jeeweb.common.bean.UiPropertyVo;
import cn.jeeweb.common.http.DuplicateValid;
import cn.jeeweb.common.http.Response;
import cn.jeeweb.common.mvc.entity.DataEntity;
import cn.jeeweb.common.mybatis.mvc.parse.QueryToWrapper;
import cn.jeeweb.common.mybatis.mvc.service.ICommonService;
import cn.jeeweb.common.query.data.*;
//import cn.jeeweb.web.modules.annotate.UiPropertyField;
import cn.jeeweb.common.utils.DateUtils;
import cn.jeeweb.common.utils.SpringContextHolder;
import cn.xjzn.framework_Core.DataType;
import cn.xjzn.framework_Core.ModuleServe;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.BaseMapper;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.Serializable;
import java.lang.reflect.*;
import java.util.*;

import static cn.jeeweb.common.utils.ReflectionUtils.getSuperClassGenricType;
import static cn.jeeweb.common.utils.Reflections.getClassGenricType;

@Transactional
public class CommonServiceImpl<M extends BaseMapper<T>, T> extends ServiceImpl<M, T> implements ICommonService<T> {

    /**
     * 从Json字符串转为1个单体实例
     *
     * @param json
     * @return
     */
    public T parseObject(String json) {
        if (!StringUtils.isEmpty(json)) {
            Class<?> c = getSuperClassGenricType(this.getClass(), 1);
            //TypeReference<T> ty= new TypeReference<T>(){};
            T t = (T) JSON.parseObject(json, c);
            return t;
        } else
            return null;
    }

    @Override
    public boolean insert(String json) {
        return insert(parseObject(json));
    }

    @Override
    public T insertAndSelect(String json) {
        T entity = parseObject(json);
        if (entity != null) {
            return insertAndSelect(entity);
        }
        return null;
    }

    @Override
    public T insertAndSelect(String json, String json_) {
        return null;
    }

    @Override
    public boolean insert(T entity) {
        return super.insert(entity);
    }

    @Override
    public T insertAndSelect(T entity) {
        boolean ret = false;
        try{
            ret = super.insert(entity);
        }catch (Exception e){
            System.out.println(e.getCause());
            String errorCase = String.valueOf(e.getCause());
            if(errorCase.contains("MySQLIntegrityConstraintViolationException") && errorCase.contains("code")){
                return (T) "exist";
            }
        }

        if (ret) {
            DataEntity entity_ = entity instanceof DataEntity ? (DataEntity) entity : null;
            if (entity_ != null) {
                return selectById((Serializable) entity_.getId());
            }
        }
        return null;
    }

    @Override
    public boolean insertOrUpdate(String json) {
        boolean result = false;
        try{
            result = insertOrUpdate(parseObject(json));
        }catch (Exception e){
            String errorCase = String.valueOf(e.getCause());
            if(errorCase.contains("MySQLIntegrityConstraintViolationException") && errorCase.contains("code")){
                return false;
            }
        }
        return result;
    }

    @Override
    public boolean deleteBatchIds(String json) {
        JSONObject jsonObject = JSON.parseObject(json);
        String val = jsonObject.getString("ids").replace("[", "").replace("]", "").replace("\"", "");
        List<String> idList = java.util.Arrays.asList(val.split(","));
        boolean result = deleteBatchIds(idList);
        return result;
    }

    @Override
    public Page<T> list(Queryable queryable) {
        EntityWrapper<T> entityWrapper = new EntityWrapper<T>();
        return list(queryable, entityWrapper);
    }

    @Override
    public Page<T> list(Queryable queryable,String type, String foreignId) {
        EntityWrapper<T> entityWrapper = new EntityWrapper<T>();
        if("0".equals(type)){
            Class<?> c = getSuperClassGenricType(this.getClass(), 1);
            Field[] fields = c.getDeclaredFields();
            if (fields != null && fields.length > 0) {
                for (Field field : fields) {
                    if (field.isAnnotationPresent(UiPropertyField.class)) {
                        UiPropertyField annotation = field.getAnnotation(UiPropertyField.class);
                        int isReference = annotation.isReference();
                        ModuleServe referenceModule = annotation.referenceModuleId();
                        if (isReference == 1 && referenceModule.getValue() == ModuleServe.UNKNOWN.getValue()) {
                            String foreignColumn = field.getName();
                            entityWrapper.eq(foreignColumn, foreignId);
                        }
                    }
                }
            }
        }
        return list(queryable, entityWrapper,type);
    }

    public Page<T> list(Queryable queryable, Wrapper<T> wrapper,String type) {
        QueryToWrapper<T> queryToWrapper = new QueryToWrapper<T>();
        queryToWrapper.parseCondition(wrapper, queryable);
        // 排序问题
        queryToWrapper.parseSort(wrapper, queryable);
        Pageable pageable = queryable.getPageable();
        com.baomidou.mybatisplus.plugins.Page<T> page = new com.baomidou.mybatisplus.plugins.Page<T>(
                pageable.getPageNumber(), pageable.getPageSize());
        com.baomidou.mybatisplus.plugins.Page<T> content = selectPage(page, wrapper);

        Map<String, UiPropertyVo> map = new HashMap<String, UiPropertyVo>();
        Object object = null;
        Class<?> clazz = getSuperClassGenricType(this.getClass(), 1);
        Field[] declaredFields = clazz.getDeclaredFields();
        if (declaredFields != null && declaredFields.length > 0) {
            for (Field field : declaredFields) {
                if (field.isAnnotationPresent(UiPropertyField.class)) {
                    UiPropertyField annotation = field.getAnnotation(UiPropertyField.class);
                    String ownerPropertyName = annotation.ownerPropertyName();
                    String referenceModuleId = annotation.referenceModuleId().getValue();
                    if (cn.jeeweb.common.utils.StringUtils.isNotBlank(ownerPropertyName)) {
                        try {
                            object = clazz.newInstance();
                            UiPropertyVo uiPropertyVo = new UiPropertyVo();
                            uiPropertyVo.setOwnerPropertyName(ownerPropertyName);
                            uiPropertyVo.setReferenceModuleId(referenceModuleId);
                            map.put(field.getName(), uiPropertyVo);
                        } catch (InstantiationException e) {
                            e.printStackTrace();
                        } catch (IllegalAccessException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
        List records = content.getRecords();
        if (records != null && records.size() > 0) {
            for (Object o : records) {
                Class<?> cla = o.getClass();
                Field[] declaredField = cla.getDeclaredFields();
                if (declaredFields != null && declaredFields.length > 0) {

                    for (Field field : declaredField) {
                        restart:
                        for (Map.Entry<String, UiPropertyVo> bean : map.entrySet()) {
                            if (field.getName().equals(bean.getKey())) {
                                ModuleServe moduleServe = ModuleServe.getEnumByValue(bean.getValue().getReferenceModuleId());
                                String entityName = moduleServe.getEntityName();
                                entityName = entityName.substring(entityName.lastIndexOf(".") + 1);
                                String first = (entityName.charAt(0) + "").toLowerCase();
                                entityName = first + entityName.substring(1);
                                ICommonService service = SpringContextHolder.getBean(entityName + "Service");
                                String firstLetter = field.getName().substring(0, 1).toUpperCase();
                                // get方法名
                                String getMethodName = "get" + firstLetter + field.getName().substring(1);
                                // 获取get方法
                                Method getMethod = null;
                                String id = "";
                                try {
                                    getMethod = o.getClass().getDeclaredMethod(getMethodName);
                                    id = (String) getMethod.invoke(o);
                                    // 动态取值
                                    Object referenceBean = null;
                                    if("1".equals(type)){
                                        cn.jeeweb.common.mybatis.mvc.wrapper.EntityWrapper entityWrapper = new cn.jeeweb.common.mybatis.mvc.wrapper.EntityWrapper<>(o.getClass());
                                        entityWrapper.eq("code",id);
                                        List list = service.selectList(entityWrapper);
                                        if(list != null && list.size() > 0){
                                            referenceBean = list.get(0);
                                        }
                                    }else{
                                        referenceBean = service.selectById(id);
                                    }

                                    String setFirstLetter = bean.getValue().getOwnerPropertyName().substring(0, 1).toUpperCase();
                                    // set方法名
                                    String setMethodName = "set" + setFirstLetter + bean.getValue().getOwnerPropertyName().substring(1);
                                    // 获取属性
                                    Field field_ = o.getClass().getDeclaredField(bean.getValue().getOwnerPropertyName());
                                    // 获取set方法
                                    Method setMethod = o.getClass().getDeclaredMethod(setMethodName, field_.getType());
                                    // 通过set方法动态赋值
                                    setMethod.invoke(o, referenceBean);
                                } catch (NoSuchMethodException e) {
                                    e.printStackTrace();
                                } catch (InvocationTargetException e) {
                                    e.printStackTrace();
                                } catch (IllegalAccessException e) {
                                    e.printStackTrace();
                                } catch (NoSuchFieldException e) {
                                    e.printStackTrace();
                                }
                                break restart;
                            }
                        }
                    }
                }
            }
        }
        return new PageImpl<T>(content.getRecords(), queryable.getPageable(), content.getTotal());
    }

    @Override
    public Page<T> list(Queryable queryable, Wrapper<T> wrapper) {
        QueryToWrapper<T> queryToWrapper = new QueryToWrapper<T>();
        queryToWrapper.parseCondition(wrapper, queryable);
        // 排序问题
        queryToWrapper.parseSort(wrapper, queryable);
        Pageable pageable = queryable.getPageable();
        com.baomidou.mybatisplus.plugins.Page<T> page = new com.baomidou.mybatisplus.plugins.Page<T>(
                pageable.getPageNumber(), pageable.getPageSize());
        com.baomidou.mybatisplus.plugins.Page<T> content = selectPage(page, wrapper);

        Map<String, UiPropertyVo> map = new HashMap<String, UiPropertyVo>();
        Object object = null;
        Class<?> clazz = getSuperClassGenricType(this.getClass(), 1);
        Field[] declaredFields = clazz.getDeclaredFields();
        if (declaredFields != null && declaredFields.length > 0) {
            for (Field field : declaredFields) {
                if (field.isAnnotationPresent(UiPropertyField.class)) {
                    UiPropertyField annotation = field.getAnnotation(UiPropertyField.class);
                    String ownerPropertyName = annotation.ownerPropertyName();
                    String referenceModuleId = annotation.referenceModuleId().getValue();
                    if (cn.jeeweb.common.utils.StringUtils.isNotBlank(ownerPropertyName) && !"-1".equals(referenceModuleId)) {
                        try {
                            object = clazz.newInstance();
                            UiPropertyVo uiPropertyVo = new UiPropertyVo();
                            uiPropertyVo.setOwnerPropertyName(ownerPropertyName);
                            uiPropertyVo.setReferenceModuleId(referenceModuleId);
                            map.put(field.getName(), uiPropertyVo);
                        } catch (InstantiationException e) {
                            e.printStackTrace();
                        } catch (IllegalAccessException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
        List records = content.getRecords();
        if (records != null && records.size() > 0) {
            for (Object o : records) {
                Class<?> cla = o.getClass();
                Field[] declaredField = cla.getDeclaredFields();
                if (declaredFields != null && declaredFields.length > 0) {

                    for (Field field : declaredField) {
                        restart:
                        for (Map.Entry<String, UiPropertyVo> bean : map.entrySet()) {
                            if (field.getName().equals(bean.getKey())) {
                                ModuleServe moduleServe = ModuleServe.getEnumByValue(bean.getValue().getReferenceModuleId());
                                String entityName = moduleServe.getEntityName();
                                entityName = entityName.substring(entityName.lastIndexOf(".") + 1);
                                String first = (entityName.charAt(0) + "").toLowerCase();
                                entityName = first + entityName.substring(1);
                                ICommonService service = SpringContextHolder.getBean(entityName + "Service");
                                String firstLetter = field.getName().substring(0, 1).toUpperCase();
                                // get方法名
                                String getMethodName = "get" + firstLetter + field.getName().substring(1);
                                // 获取get方法
                                Method getMethod = null;
                                String id = "";
                                try {
                                    getMethod = o.getClass().getDeclaredMethod(getMethodName);
                                    id = (String) getMethod.invoke(o);
                                    // 动态取值
                                    Object referenceBean  = service.selectById(id);
                                    String setFirstLetter = bean.getValue().getOwnerPropertyName().substring(0, 1).toUpperCase();
                                    // set方法名
                                    String setMethodName = "set" + setFirstLetter + bean.getValue().getOwnerPropertyName().substring(1);
                                    // 获取属性
                                    Field field_ = o.getClass().getDeclaredField(bean.getValue().getOwnerPropertyName());
                                    // 获取set方法
                                    Method setMethod = o.getClass().getDeclaredMethod(setMethodName, field_.getType());
                                    // 通过set方法动态赋值
                                    setMethod.invoke(o, referenceBean);
                                } catch (NoSuchMethodException e) {
                                    e.printStackTrace();
                                } catch (InvocationTargetException e) {
                                    e.printStackTrace();
                                } catch (IllegalAccessException e) {
                                    e.printStackTrace();
                                } catch (NoSuchFieldException e) {
                                    e.printStackTrace();
                                }
                                break restart;
                            }
                        }
                    }
                }
            }
        }
        return new PageImpl<T>(content.getRecords(), queryable.getPageable(), content.getTotal());
    }

    @Override
    public List<T> listWithNoPage(Queryable queryable) {
        EntityWrapper<T> entityWrapper = new EntityWrapper<T>();
        return listWithNoPage(queryable, entityWrapper);
    }

    @Override
    public List<T> listWithNoPage(Queryable queryable, String foreignId) {
        EntityWrapper<T> entityWrapper = new EntityWrapper<T>();
        Class<?> c = getSuperClassGenricType(this.getClass(), 1);
        Field[] fields = c.getDeclaredFields();
        if (fields != null && fields.length > 0) {
            for (Field field : fields) {
                if (field.isAnnotationPresent(UiPropertyField.class)) {
                    UiPropertyField annotation = field.getAnnotation(UiPropertyField.class);
                    int isReference = annotation.isReference();
                    ModuleServe referenceModule = annotation.referenceModuleId();
                    if (isReference == 1 && referenceModule.getValue() == ModuleServe.UNKNOWN.getValue()) {
                        String foreignColumn = field.getName();
                        entityWrapper.eq(foreignColumn, foreignId);
                    }
                }
            }
        }
        return listWithNoPage(queryable, entityWrapper);
    }

    @Override
    public List<T> listWithNoPage(Queryable queryable, Wrapper<T> wrapper) {
        QueryToWrapper<T> queryToWrapper = new QueryToWrapper<T>();

        queryToWrapper.parseCondition(wrapper, queryable);
        // 排序问题
        queryToWrapper.parseSort(wrapper, queryable);
        List<T> content = selectList(wrapper);
        return content;
    }

    @Override
    public Boolean doValid(DuplicateValid duplicateValid, Wrapper<T> wrapper) {
        Boolean valid = Boolean.FALSE;
        String queryType = duplicateValid.getQueryType();
        if (StringUtils.isEmpty(queryType)) {
            queryType = "table";
        }
        if (queryType.equals("table")) {
            valid = validTable(duplicateValid, wrapper);
        }
        return valid;
    }

    @Override
    public boolean deleteById(String json) {
        String id = "";
        try {
            JSONObject jsonObject = JSON.parseObject(json);
            id = jsonObject.getString("id");
        } catch (Exception e) {
            id = json;
        }
        boolean result = super.deleteById(id);
        return result;
    }

    @Override
    public T getById(String json) {
        String id_ = "";
        try {
            JSONObject jsonObject = JSON.parseObject(json);
            id_ = jsonObject.getString("id");
        } catch (Exception e) {
            id_ = json;
        }
        T o = selectById(id_);
        if(o != null){
            initReferenceObject(o,"0");
            initSubListData(o);
        }
        return o;
    }

    public void initReferenceObject(Object o,String flag) {
        Map<String, UiPropertyVo> map = new HashMap<String, UiPropertyVo>();
        Object object = null;
        Class<?> clazz = getSuperClassGenricType(this.getClass(), 1);
        Field[] declaredFields = clazz.getDeclaredFields();
        if (declaredFields != null && declaredFields.length > 0) {
            for (Field field : declaredFields) {
                if (field.isAnnotationPresent(UiPropertyField.class)) {
                    UiPropertyField annotation = field.getAnnotation(UiPropertyField.class);
                    String ownerPropertyName = annotation.ownerPropertyName();
                    String referenceModuleId = annotation.referenceModuleId().getValue();
                    if (cn.jeeweb.common.utils.StringUtils.isNotBlank(ownerPropertyName) && !"-1".equals(referenceModuleId)) {
                        try {
                            object = clazz.newInstance();
                            UiPropertyVo uiPropertyVo = new UiPropertyVo();
                            uiPropertyVo.setOwnerPropertyName(ownerPropertyName);
                            uiPropertyVo.setReferenceModuleId(referenceModuleId);
                            map.put(field.getName(), uiPropertyVo);
                        } catch (InstantiationException e) {
                            e.printStackTrace();
                        } catch (IllegalAccessException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }

        Class<?> cla = o.getClass();
        Field[] declaredField = cla.getDeclaredFields();
        if (declaredFields != null && declaredFields.length > 0) {

            for (Field field : declaredField) {
                restart:
                for (Map.Entry<String, UiPropertyVo> bean : map.entrySet()) {
                    if (field.getName().equals(bean.getKey())) {
                        ModuleServe moduleServe = ModuleServe.getEnumByValue(bean.getValue().getReferenceModuleId());
                        String entityName = moduleServe.getEntityName();
                        entityName = entityName.substring(entityName.lastIndexOf(".") + 1);
                        String first = (entityName.charAt(0) + "").toLowerCase();
                        entityName = first + entityName.substring(1);
                        ICommonService service = SpringContextHolder.getBean(entityName + "Service");
                        String firstLetter = field.getName().substring(0, 1).toUpperCase();
                        // get方法名
                        String getMethodName = "get" + firstLetter + field.getName().substring(1);
                        // 获取get方法
                        Method getMethod = null;
                        String id = "";
                        try {
                            getMethod = o.getClass().getDeclaredMethod(getMethodName);
                            id = (String) getMethod.invoke(o);
                            // 动态取值
                            Object referenceBean = null;
                            if("0".equals(flag)){
                                referenceBean = service.selectById(id);
                            }else if("1".equals(flag)){
                                cn.jeeweb.common.mybatis.mvc.wrapper.EntityWrapper entityWrapper = new cn.jeeweb.common.mybatis.mvc.wrapper.EntityWrapper<>(o.getClass());
                                entityWrapper.eq("code",id);
                                List list = service.selectList(entityWrapper);
                                if(list != null && list.size() > 0){
                                    referenceBean = list.get(0);
                                }
                            }

                            String setFirstLetter = bean.getValue().getOwnerPropertyName().substring(0, 1).toUpperCase();
                            // set方法名
                            String setMethodName = "set" + setFirstLetter + bean.getValue().getOwnerPropertyName().substring(1);
                            // 获取属性
                            Field field_ = o.getClass().getDeclaredField(bean.getValue().getOwnerPropertyName());
                            // 获取set方法
                            Method setMethod = o.getClass().getDeclaredMethod(setMethodName, field_.getType());
                            // 通过set方法动态赋值
                            setMethod.invoke(o, referenceBean);
                        } catch (NoSuchMethodException e) {
                            e.printStackTrace();
                        } catch (InvocationTargetException e) {
                            e.printStackTrace();
                        } catch (IllegalAccessException e) {
                            e.printStackTrace();
                        } catch (NoSuchFieldException e) {
                            e.printStackTrace();
                        }
                        break restart;
                    }
                }
            }
        }
    }

    //子类数据的查询
    public void initSubListData(Object o) {
        Class<?> cla = o.getClass();
        Field[] declaredField = cla.getDeclaredFields();
        if (declaredField != null && declaredField.length > 0) {
            for (Field field : declaredField) {
                if (field.isAnnotationPresent(UiPropertyField.class)) {
                    UiPropertyField annotation = field.getAnnotation(UiPropertyField.class);
                    DataType dataType = annotation.dataType();
                    String relationIdName = annotation.relationIdName();
                    String ownerPropertyName = annotation.ownerPropertyName();
                    if (dataType.getValue() == DataType.SUBLISTDATATYPE.getValue()) {
                        Type genericType = field.getGenericType();
                        if (null == genericType) {
                            continue;
                        }
                        if (genericType instanceof ParameterizedType) {
                            ParameterizedType pt = (ParameterizedType) genericType;
                            // 得到泛型里的class类型对象
                            Class<?> actualTypeArgument = (Class<?>) pt.getActualTypeArguments()[0];
                            String entityName = actualTypeArgument.getName();
                            entityName = entityName.substring(entityName.lastIndexOf(".") + 1);
                            String first = (entityName.charAt(0) + "").toLowerCase();
                            entityName = first + entityName.substring(1);
                            ICommonService service = SpringContextHolder.getBean(entityName + "Service");
                            // get方法名
                            String getMethodName = "getId";
                            // 获取get方法
                            Method getMethod = null;
                            try {
                                getMethod = o.getClass().getMethod(getMethodName);
                                String id = (String) getMethod.invoke(o);
                                cn.jeeweb.common.mybatis.mvc.wrapper.EntityWrapper<Object> entityWrapper = new cn.jeeweb.common.mybatis.mvc.wrapper.EntityWrapper<>();
                                entityWrapper.eq(relationIdName, id);
                                List list = service.selectList(entityWrapper);
                                String setFirstLetter = ownerPropertyName.substring(0, 1).toUpperCase();
                                // set方法名
                                String setMethodName = "set" + setFirstLetter + ownerPropertyName.substring(1);
                                // 获取属性
                                Field field_ = o.getClass().getDeclaredField(ownerPropertyName);
                                // 获取set方法
                                Method setMethod = o.getClass().getDeclaredMethod(setMethodName, field_.getType());
                                // 通过set方法动态赋值
                                setMethod.invoke(o, list);
                                System.out.println(list);
                            } catch (NoSuchMethodException e) {
                                e.printStackTrace();
                            } catch (InvocationTargetException e) {
                                e.printStackTrace();
                            } catch (IllegalAccessException e) {
                                e.printStackTrace();
                            } catch (NoSuchFieldException e) {
                                e.printStackTrace();
                            }

                        }
                    }
                }
            }
        }
    }

    @Override
    public boolean insertRelationTable(String json) {
        T t = parseObject(json);
//        insert(t);
        T object = insertAndSelect(t);
        String objectJson = JSONObject.toJSONString(object);
        JSONObject jsonObject = JSON.parseObject(objectJson);
        String id = jsonObject.getString("id");
        Class<?> clazz = t.getClass();
        Field[] declaredFields = clazz.getDeclaredFields();
        if (declaredFields != null && declaredFields.length > 0) {
            for (Field field : declaredFields) {
                if (field.isAnnotationPresent(UiPropertyField.class)) {
                    UiPropertyField annotation = field.getAnnotation(UiPropertyField.class);
                    DataType dataType = annotation.dataType();
                    String relationIdName = annotation.relationIdName();
                    if (dataType.getValue() == DataType.SUBLISTDATATYPE.getValue()) {
                        Type genericType = field.getGenericType();
                        if (null == genericType) {
                            continue;
                        }
                        if (genericType instanceof ParameterizedType) {
                            ParameterizedType pt = (ParameterizedType) genericType;
                            // 得到泛型里的class类型对象
                            Class<?> actualTypeArgument = (Class<?>) pt.getActualTypeArguments()[0];
                            String childClassName = actualTypeArgument.getName();
                            String firstLetter = field.getName().substring(0, 1).toUpperCase();
                            // get方法名
                            String getMethodName = "get" + firstLetter + field.getName().substring(1);
                            // 获取get方法
                            Method getMethod = null;
                            try {
                                getMethod = t.getClass().getDeclaredMethod(getMethodName);
                                Object o = getMethod.invoke(t);
                                insertOrUpdateBatchList(childClassName, o, id, relationIdName,"add");
                            } catch (NoSuchMethodException e) {
                                e.printStackTrace();
                            } catch (InvocationTargetException e) {
                                e.printStackTrace();
                            } catch (IllegalAccessException e) {
                                e.printStackTrace();
                            }

                            System.out.println(childClassName);
                        }
                    }
                }
            }
        }
        return true;
    }

    @Override
    public boolean updateRelationTable(String json) {
        T t = parseObject(json);
        insertOrUpdate(t);
        String objectJson = JSONObject.toJSONString(t);
        JSONObject jsonObject = JSON.parseObject(objectJson);
        String id = jsonObject.getString("id");
        Class<?> clazz = t.getClass();
        Field[] declaredFields = clazz.getDeclaredFields();
        if (declaredFields != null && declaredFields.length > 0) {
            for (Field field : declaredFields) {
                if (field.isAnnotationPresent(UiPropertyField.class)) {
                    UiPropertyField annotation = field.getAnnotation(UiPropertyField.class);
                    DataType dataType = annotation.dataType();
                    String relationIdName = annotation.relationIdName();
                    if (dataType.getValue() == DataType.SUBLISTDATATYPE.getValue()) {
                        Type genericType = field.getGenericType();
                        if (null == genericType) {
                            continue;
                        }
                        if (genericType instanceof ParameterizedType) {
                            ParameterizedType pt = (ParameterizedType) genericType;
                            // 得到泛型里的class类型对象
                            Class<?> actualTypeArgument = (Class<?>) pt.getActualTypeArguments()[0];
                            String childClassName = actualTypeArgument.getName();
                            String firstLetter = field.getName().substring(0, 1).toUpperCase();
                            // get方法名
                            String getMethodName = "get" + firstLetter + field.getName().substring(1);
                            // 获取get方法
                            Method getMethod = null;
                            try {
                                getMethod = t.getClass().getDeclaredMethod(getMethodName);
                                Object o = getMethod.invoke(t);
                                insertOrUpdateBatchList(childClassName, o,id,relationIdName,"");
                            } catch (NoSuchMethodException e) {
                                e.printStackTrace();
                            } catch (InvocationTargetException e) {
                                e.printStackTrace();
                            } catch (IllegalAccessException e) {
                                e.printStackTrace();
                            }
                            System.out.println(childClassName);
                        }
                    }
                }
            }
        }
        return true;
    }

    @Override
    public Response export(Page pageBean, String title) {
        Response response = Response.ok("导出成功");
        List list = Collections.emptyList();
        list = pageBean.getContent();
        String secondTitle = "导出时间：" + DateUtils.getDateTime();
        Workbook book = ExcelExportUtil.exportExcel(new ExportParams(
                title, title, title), getSuperClassGenricType(this.getClass(), 1), list);
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        try {
            book.write(bos);
        } catch (IOException e) {
            e.printStackTrace();
        }
        byte[] bytes = bos.toByteArray();
        String bytesRes = cn.jeeweb.common.utils.StringUtils.bytesToHexString2(bytes);
        title = title + "-" + DateUtils.getDateTime();
        response.put("bytes", bytesRes);
        response.put("title", title);
        return response;
    }

    @Override
    public boolean deleteRelationTable(String json) {
        T t = parseObject(json);
        String objectJson = JSONObject.toJSONString(t);
        JSONObject jsonObject = JSON.parseObject(objectJson);
        String id = jsonObject.getString("id");
        Class<?> clazz = t.getClass();
        Field[] declaredFields = clazz.getDeclaredFields();
        if (declaredFields != null && declaredFields.length > 0) {
            for (Field field : declaredFields) {
                if (field.isAnnotationPresent(UiPropertyField.class)) {
                    UiPropertyField annotation = field.getAnnotation(UiPropertyField.class);
                    DataType dataType = annotation.dataType();
                    String relationIdName = annotation.relationIdName();
                    if (dataType.getValue() == DataType.SUBLISTDATATYPE.getValue()) {
                        Type genericType = field.getGenericType();
                        if (null == genericType) {
                            continue;
                        }
                        if (genericType instanceof ParameterizedType) {
                            ParameterizedType pt = (ParameterizedType) genericType;
                            // 得到泛型里的class类型对象
                            Class<?> actualTypeArgument = (Class<?>) pt.getActualTypeArguments()[0];
                            String childClassName = actualTypeArgument.getName();
                            String firstLetter = field.getName().substring(0, 1).toUpperCase();
                            // get方法名
                            String getMethodName = "get" + firstLetter + field.getName().substring(1);
                            // 获取get方法
                            Method getMethod = null;
                            try {
                                getMethod = t.getClass().getDeclaredMethod(getMethodName);
                                Object o = getMethod.invoke(t);
                                insertOrUpdateBatchList(childClassName, o,id,relationIdName,"");
                            } catch (NoSuchMethodException e) {
                                e.printStackTrace();
                            } catch (InvocationTargetException e) {
                                e.printStackTrace();
                            } catch (IllegalAccessException e) {
                                e.printStackTrace();
                            }
                            System.out.println(childClassName);
                        }
                    }
                }
            }
        }
        return true;
    }

    @Override
    public boolean insertOrUpdate(String json, String json_) {
        return false;
    }

    /**
     *
     * @param entityName
     * @param o
     * @param foreignId 主表id值
     * @param relationIdName 从表的关联字段
     * @param type  操作类型，delete:删除
     */
    private void insertOrUpdateBatchList(String entityName, Object o, String foreignId, String relationIdName, String type) {
        entityName = entityName.substring(entityName.lastIndexOf(".") + 1);
        String first = (entityName.charAt(0) + "").toLowerCase();
        entityName = first + entityName.substring(1);
        ICommonService service = SpringContextHolder.getBean(entityName + "Service");
        List list = new ArrayList<>();
        if (o != null) {
            list = (List) o;
        }
        if(!"add".equals(type)){
            EntityWrapper<Object> entityWrapper = new EntityWrapper<>();
            entityWrapper.eq(relationIdName,foreignId);
            service.delete(entityWrapper);
        }
        if (list.size() > 0) {
            for (int i = 0; i < list.size(); i++) {
                Object object = list.get(i);
                // set方法名
                String setFirstLetter = relationIdName.substring(0, 1).toUpperCase();
                String setMethodName = "set" + setFirstLetter + relationIdName.substring(1);
                // 获取属性
                Field field_ = null;
                try {
                    field_ = object.getClass().getDeclaredField(relationIdName);
                    // 获取set方法
                    Method setMethod = object.getClass().getDeclaredMethod(setMethodName, field_.getType());
                    // 通过set方法动态赋值
                    setMethod.invoke(object, foreignId);
                } catch (NoSuchFieldException e) {
                    e.printStackTrace();
                } catch (NoSuchMethodException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                }
                service.insert(object);
            }
//            else{
//                for (int i = 0; i < list.size(); i++) {
//                    Object object = list.get(i);
//                    JSONObject jsonObject = JSON.parseObject(JSON.toJSONString(object));
//                    String id = (String) jsonObject.get("id");
//                    if (cn.jeeweb.common.utils.StringUtils.isNotBlank(id)) {
//                        service.insertOrUpdate(object);
//                    } else {
//                        // set方法名
//                        String setFirstLetter = relationIdName.substring(0, 1).toUpperCase();
//                        String setMethodName = "set" + setFirstLetter + relationIdName.substring(1);
//                        // 获取属性
//                        Field field_ = null;
//                        try {
//                            field_ = object.getClass().getDeclaredField(relationIdName);
//                            // 获取set方法
//                            Method setMethod = object.getClass().getDeclaredMethod(setMethodName, field_.getType());
//                            // 通过set方法动态赋值
//                            setMethod.invoke(object, foreignId);
//                        } catch (NoSuchFieldException e) {
//                            e.printStackTrace();
//                        } catch (NoSuchMethodException e) {
//                            e.printStackTrace();
//                        } catch (IllegalAccessException e) {
//                            e.printStackTrace();
//                        } catch (InvocationTargetException e) {
//                            e.printStackTrace();
//                        }
//                        service.insert(object);
//                    }
//                }
//            }
        }
    }
    
    private Boolean validTable(DuplicateValid duplicateValid, Wrapper<T> wrapper) {
        Integer num = null;
        String extendName = duplicateValid.getExtendName();
        String extendParam = duplicateValid.getExtendParam();
        if (!StringUtils.isEmpty(extendParam)) {
            // [2].编辑页面校验
            wrapper.eq(duplicateValid.getName(), duplicateValid.getParam()).ne(extendName, extendParam);
            num = baseMapper.selectCount(wrapper);
        } else {
            // [1].添加页面校验
            wrapper.eq(duplicateValid.getName(), duplicateValid.getParam());
            num = baseMapper.selectCount(wrapper);
        }

        if (num == null || num == 0) {
            // 该值可用
            return true;
        } else {
            // 该值不可用
            return false;
        }
    }

}